using UnityEngine;

[AddComponentMenu("BoneCracker Games/Realistic Car Controller/Camera/Main Camera")]
public class RCC_Camera : MonoBehaviour
{
	public enum CameraMode
	{
		TPS = 0,
		FPS = 1,
		WHEEL = 2,
		FIXED = 3
	}

	public Transform playerCar;

	private Rigidbody playerRigid;

	private Camera cam;

	public GameObject pivot;

	private GameObject boundCenter;

	public CameraMode cameraMode;

	public float distance = 6f;

	public float height = 2f;

	private float heightDamping = 5f;

	private float rotationDamping = 3f;

	public float targetFieldOfView = 60f;

	public float minimumFOV = 55f;

	public float maximumFOV = 70f;

	public float hoodCameraFOV = 70f;

	public float wheelCameraFOV = 60f;

	public float maximumTilt = 15f;

	private float tiltAngle;

	internal int cameraSwitchCount;

	private RCC_HoodCamera hoodCam;

	private RCC_WheelCamera wheelCam;

	private RCC_FixedCamera fixedCam;

	private Vector3 targetPosition = Vector3.zero;

	private float speed;

	private Vector3 localVector;

	private Vector3 collisionPos;

	private Quaternion collisionRot;

	private float index;

	private void Awake()
	{
		cam = GetComponentInChildren<Camera>();
	}

	public void GetPlayerCar()
	{
		if ((bool)playerCar)
		{
			cameraMode = CameraMode.TPS;
			playerRigid = playerCar.GetComponent<Rigidbody>();
			hoodCam = playerCar.GetComponentInChildren<RCC_HoodCamera>();
			wheelCam = playerCar.GetComponentInChildren<RCC_WheelCamera>();
			fixedCam = Object.FindObjectOfType<RCC_FixedCamera>();
			base.transform.position = playerCar.transform.position;
			base.transform.rotation = playerCar.transform.rotation * Quaternion.Euler(10f, 0f, 0f);
			if ((bool)playerCar.GetComponent<RCC_CameraConfig>())
			{
				playerCar.GetComponent<RCC_CameraConfig>().SetCameraSettings();
			}
		}
	}

	public void SetPlayerCar(GameObject player)
	{
	}

	private void Update()
	{
		if (!playerCar || !playerRigid)
		{
			GetPlayerCar();
			return;
		}
		speed = Mathf.Lerp(speed, playerRigid.velocity.magnitude * 3.6f, Time.deltaTime * 0.5f);
		if (index > 0f)
		{
			index -= Time.deltaTime * 5f;
		}
		if (cameraMode == CameraMode.TPS)
		{
		}
		cam.fieldOfView = Mathf.Lerp(cam.fieldOfView, targetFieldOfView, Time.deltaTime * 3f);
	}

	private void LateUpdate()
	{
		if (!playerCar || !playerRigid || !playerCar.gameObject.activeSelf)
		{
			return;
		}
		if (Input.GetKeyDown(RCC_Settings.Instance.changeCameraKB))
		{
			ChangeCamera();
		}
		switch (cameraMode)
		{
		case CameraMode.TPS:
			TPS();
			break;
		case CameraMode.FPS:
			if ((bool)hoodCam)
			{
				FPS();
			}
			else
			{
				ChangeCamera();
			}
			break;
		case CameraMode.WHEEL:
			if ((bool)wheelCam)
			{
				WHEEL();
			}
			else
			{
				ChangeCamera();
			}
			break;
		case CameraMode.FIXED:
			if ((bool)fixedCam)
			{
				FIXED();
			}
			else
			{
				ChangeCamera();
			}
			break;
		}
	}

	public void ChangeCamera()
	{
		cameraSwitchCount++;
		if (cameraSwitchCount >= 4)
		{
			cameraSwitchCount = 0;
		}
		if ((bool)fixedCam)
		{
			fixedCam.canTrackNow = false;
		}
		switch (cameraSwitchCount)
		{
		case 0:
			cameraMode = CameraMode.TPS;
			break;
		case 1:
			cameraMode = CameraMode.FPS;
			break;
		case 2:
			cameraMode = CameraMode.WHEEL;
			break;
		case 3:
			cameraMode = CameraMode.FIXED;
			break;
		}
	}

	private void FPS()
	{
		if (base.transform.parent != hoodCam.transform)
		{
			base.transform.SetParent(hoodCam.transform, false);
			base.transform.position = hoodCam.transform.position;
			base.transform.rotation = hoodCam.transform.rotation;
			targetFieldOfView = hoodCameraFOV;
			hoodCam.FixShake();
		}
	}

	private void WHEEL()
	{
		if (base.transform.parent != wheelCam.transform)
		{
			base.transform.SetParent(wheelCam.transform, false);
			base.transform.position = wheelCam.transform.position;
			base.transform.rotation = wheelCam.transform.rotation;
			targetFieldOfView = wheelCameraFOV;
		}
	}

	private void TPS()
	{
		if (base.transform.parent != null)
		{
			base.transform.SetParent(null);
		}
		if (targetPosition == Vector3.zero)
		{
			targetPosition = playerCar.position;
			targetPosition -= base.transform.rotation * Vector3.forward * distance;
			base.transform.position = targetPosition;
		}
		speed = playerRigid.transform.InverseTransformDirection(playerRigid.velocity).z * 3.6f;
		targetFieldOfView = Mathf.Lerp(minimumFOV, maximumFOV, speed / 150f) + 5f * Mathf.Cos(1f * index);
		tiltAngle = Mathf.Lerp(0f, maximumTilt * (float)(int)Mathf.Clamp(0f - playerCar.InverseTransformDirection(playerRigid.velocity).x, -1f, 1f), Mathf.Abs(playerCar.InverseTransformDirection(playerRigid.velocity).x) / 50f);
		float b = playerCar.eulerAngles.y;
		float num = playerCar.position.y + height;
		float y = base.transform.eulerAngles.y;
		float y2 = base.transform.position.y;
		rotationDamping = Mathf.Lerp(0f, 3f, playerRigid.velocity.magnitude * 3f / 40f);
		if (speed < -10f)
		{
			b = playerCar.eulerAngles.y + 180f;
		}
		y = Mathf.LerpAngle(y, b, rotationDamping * Time.deltaTime);
		y2 = Mathf.Lerp(y2, num + Mathf.Lerp(-0.5f, 0f, speed / 20f), heightDamping * Time.deltaTime);
		Quaternion quaternion = Quaternion.Euler(0f, y, 0f);
		base.transform.position = playerCar.position;
		base.transform.position -= quaternion * Vector3.forward * distance;
		base.transform.position = new Vector3(base.transform.position.x, y2, base.transform.position.z);
		base.transform.LookAt(new Vector3(playerCar.position.x, playerCar.position.y + 1f, playerCar.position.z));
		base.transform.eulerAngles = new Vector3(base.transform.eulerAngles.x, base.transform.eulerAngles.y, Mathf.Clamp(tiltAngle, -10f, 10f));
		collisionPos = Vector3.Lerp(collisionPos, Vector3.zero, Time.deltaTime * 5f);
		collisionRot = Quaternion.Lerp(collisionRot, Quaternion.identity, Time.deltaTime * 5f);
		pivot.transform.localPosition = Vector3.Lerp(pivot.transform.localPosition, collisionPos, Time.deltaTime * 5f);
		pivot.transform.localRotation = Quaternion.Lerp(pivot.transform.localRotation, collisionRot, Time.deltaTime * 5f);
	}

	private void FIXED()
	{
		if (base.transform.parent != fixedCam.transform)
		{
			base.transform.SetParent(fixedCam.transform, false);
			base.transform.position = fixedCam.transform.position;
			base.transform.rotation = fixedCam.transform.rotation;
			targetFieldOfView = 60f;
			fixedCam.currentCar = playerCar;
			fixedCam.canTrackNow = true;
		}
		if (fixedCam.transform.parent != null)
		{
			fixedCam.transform.SetParent(null);
		}
	}

	public void Collision(Collision collision)
	{
		if (base.enabled && cameraMode == CameraMode.TPS)
		{
			Vector3 relativeVelocity = collision.relativeVelocity;
			relativeVelocity *= 1f - Mathf.Abs(Vector3.Dot(base.transform.up, collision.contacts[0].normal));
			float num = Mathf.Abs(Vector3.Dot(collision.contacts[0].normal, relativeVelocity.normalized));
			if (relativeVelocity.magnitude * num >= 5f)
			{
				localVector = base.transform.InverseTransformDirection(relativeVelocity) / 30f;
				collisionPos -= localVector * 3f;
				collisionRot = Quaternion.Euler(new Vector3((0f - localVector.z) * 30f, (0f - localVector.y) * 30f, (0f - localVector.x) * 30f));
				targetFieldOfView = cam.fieldOfView - Mathf.Clamp(collision.relativeVelocity.magnitude, 0f, 15f);
				index = Mathf.Clamp(collision.relativeVelocity.magnitude / 5f, 0f, 10f);
			}
		}
	}
}
